//! # 消息总线建造者
//!
//! 提供统一的消息总线构建接口，支持链式配置和多种后端

use async_trait::async_trait;
use std::sync::Arc;

use crate::config::{MessageBusConfig, MessageBusType};
use crate::error::{MessageBusError, MessageBusResult};
use crate::bus::MessageBus;
use crate::memory::InMemoryMessageBus;
use crate::metrics::MessageBusMetrics;

/// 消息总线建造者
pub struct MessageBusBuilder {
    config: MessageBusConfig,
    metrics: Option<Arc<MessageBusMetrics>>,
    interceptors: Vec<Box<dyn crate::bus::MessageInterceptor>>,
}

impl MessageBusBuilder {
    /// 创建新的建造者
    pub fn new() -> Self {
        Self {
            config: MessageBusConfig::default(),
            metrics: None,
            interceptors: Vec::new(),
        }
    }

    /// 使用指定配置创建建造者
    pub fn with_config(config: MessageBusConfig) -> Self {
        Self {
            config,
            metrics: None,
            interceptors: Vec::new(),
        }
    }

    /// 设置消息总线类型
    pub fn bus_type(mut self, bus_type: MessageBusType) -> Self {
        self.config.bus_type = bus_type;
        self
    }

    /// 设置最大连接数
    pub fn max_connections(mut self, max_connections: usize) -> Self {
        self.config.max_connections = max_connections;
        self
    }

    /// 设置重试次数
    pub fn retry_attempts(mut self, retry_attempts: u32) -> Self {
        self.config.retry_attempts = retry_attempts;
        self
    }

    /// 设置重试延迟（毫秒）
    pub fn retry_delay_ms(mut self, retry_delay_ms: u64) -> Self {
        self.config.retry_delay_ms = retry_delay_ms;
        self
    }

    /// 启用指标收集
    pub fn enable_metrics(mut self) -> Self {
        self.config.enable_metrics = true;
        self
    }

    /// 禁用指标收集
    pub fn disable_metrics(mut self) -> Self {
        self.config.enable_metrics = false;
        self
    }

    /// 设置指标端口
    pub fn metrics_port(mut self, port: u16) -> Self {
        self.config.metrics_port = port;
        self
    }

    /// 启用追踪
    pub fn enable_tracing(mut self) -> Self {
        self.config.enable_tracing = true;
        self
    }

    /// 禁用追踪
    pub fn disable_tracing(mut self) -> Self {
        self.config.enable_tracing = false;
        self
    }

    /// 设置缓冲区大小
    pub fn buffer_size(mut self, buffer_size: usize) -> Self {
        self.config.buffer_size = buffer_size;
        self
    }

    /// 设置最大消息大小（字节）
    pub fn max_message_size(mut self, max_message_size: usize) -> Self {
        self.config.max_message_size = max_message_size;
        self
    }

    /// 设置消息 TTL（毫秒）
    pub fn message_ttl_ms(mut self, message_ttl_ms: u64) -> Self {
        self.config.message_ttl_ms = message_ttl_ms;
        self
    }

    /// 添加自定义属性
    pub fn custom_property(mut self, key: String, value: String) -> Self {
        self.config.custom_properties.insert(key, value);
        self
    }

    /// 设置 Redis 配置
    pub fn redis_config(mut self, redis_config: crate::config::RedisConfig) -> Self {
        self.config.redis = Some(redis_config);
        self
    }

    /// 设置 Kafka 配置
    pub fn kafka_config(mut self, kafka_config: crate::config::KafkaConfig) -> Self {
        self.config.kafka = Some(kafka_config);
        self
    }

    /// 设置 NATS 配置
    pub fn nats_config(mut self, nats_config: crate::config::NatsConfig) -> Self {
        self.config.nats = Some(nats_config);
        self
    }

    /// 添加消息拦截器
    pub fn add_interceptor(mut self, interceptor: Box<dyn crate::bus::MessageInterceptor>) -> Self {
        self.interceptors.push(interceptor);
        self
    }

    /// 添加自定义指标收集器
    pub fn with_metrics(mut self, metrics: Arc<MessageBusMetrics>) -> Self {
        self.metrics = Some(metrics);
        self
    }

    /// 从环境变量加载配置
    pub fn from_env(mut self) -> MessageBusResult<Self> {
        self.config = MessageBusConfig::from_env()?;
        Ok(self)
    }

    /// 从文件加载配置
    pub fn from_file(mut self, path: &str) -> MessageBusResult<Self> {
        self.config = MessageBusConfig::from_file(path)?;
        Ok(self)
    }

    /// 构建消息总线
    pub async fn build(self) -> MessageBusResult<Arc<dyn MessageBus>> {
        // 验证配置
        self.config.validate()?;

        // 创建指标收集器
        let metrics = if self.config.enable_metrics {
            Some(self.metrics.unwrap_or_else(|| {
                Arc::new(MessageBusMetrics::new())
            }))
        } else {
            None
        };

        // 根据配置类型创建相应的消息总线
        let bus: Arc<dyn MessageBus> = match self.config.bus_type {
            MessageBusType::Memory => {
                let mut builder = InMemoryMessageBus::builder()
                    .buffer_size(self.config.buffer_size)
                    .max_message_size(self.config.max_message_size)
                    .enable_metrics(self.config.enable_metrics);

                let memory_bus = builder.build().await?;
                Arc::new(memory_bus) as Arc<dyn MessageBus>
            }
            MessageBusType::Redis => {
                if self.config.redis.is_none() {
                    return Err(MessageBusError::config_error(
                        "redis",
                        "null",
                        "Redis 配置缺失"
                    ));
                }
                // TODO: 实现 Redis 消息总线
                return Err(MessageBusError::internal_error("Redis 消息总线尚未实现"));
            }
            MessageBusType::Kafka => {
                if self.config.kafka.is_none() {
                    return Err(MessageBusError::config_error(
                        "kafka",
                        "null",
                        "Kafka 配置缺失"
                    ));
                }
                // TODO: 实现 Kafka 消息总线
                return Err(MessageBusError::internal_error("Kafka 消息总线尚未实现"));
            }
            MessageBusType::Nats => {
                if self.config.nats.is_none() {
                    return Err(MessageBusError::config_error(
                        "nats",
                        "null",
                        "NATS 配置缺失"
                    ));
                }
                // TODO: 实现 NATS 消息总线
                return Err(MessageBusError::internal_error("NATS 消息总线尚未实现"));
            }
        };

        Ok(bus)
    }
}

impl Default for MessageBusBuilder {
    fn default() -> Self {
        Self::new()
    }
}

/// 消息总线工厂实用方法
pub struct MessageBusUtils;

impl MessageBusUtils {
    /// 创建默认消息总线
    pub async fn create_default() -> MessageBusResult<Arc<dyn MessageBus>> {
        MessageBusBuilder::new().build().await
    }

    /// 创建内存消息总线
    pub async fn create_memory() -> MessageBusResult<Arc<dyn MessageBus>> {
        MessageBusBuilder::new()
            .bus_type(MessageBusType::Memory)
            .build()
            .await
    }

    /// 从配置创建消息总线
    pub async fn create_with_config(config: MessageBusConfig) -> MessageBusResult<Arc<dyn MessageBus>> {
        MessageBusBuilder::with_config(config).build().await
    }

    /// 从环境变量创建消息总线
    pub async fn create_from_env() -> MessageBusResult<Arc<dyn MessageBus>> {
        MessageBusBuilder::new()
            .from_env()?
            .build()
            .await
    }

    /// 从文件创建消息总线
    pub async fn create_from_file(path: &str) -> MessageBusResult<Arc<dyn MessageBus>> {
        MessageBusBuilder::new()
            .from_file(path)?
            .build()
            .await
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::message::Message;
    use serde_json::json;

    #[tokio::test]
    async fn test_builder_default() {
        let bus = MessageBusBuilder::new()
            .build()
            .await
            .expect("Failed to build message bus");

        assert_eq!(bus.list_topics().await.unwrap().len(), 0);
    }

    #[tokio::test]
    async fn test_builder_with_config() {
        let config = MessageBusConfig {
            bus_type: MessageBusType::Memory,
            buffer_size: 500,
            enable_metrics: true,
            ..Default::default()
        };

        let bus = MessageBusBuilder::with_config(config)
            .build()
            .await
            .expect("Failed to build message bus");

        // 测试基本功能
        let subscriber = bus.subscribe("test.*").await.unwrap();
        let message = Message::new("test.topic", json!({"test": "data"}));
        
        bus.publish(message).await.unwrap();
        let received = subscriber.receive_timeout(100).await.unwrap();
        assert!(received.is_some());
    }

    #[tokio::test]
    async fn test_builder_chain() {
        let bus = MessageBusBuilder::new()
            .bus_type(MessageBusType::Memory)
            .max_connections(50)
            .retry_attempts(5)
            .retry_delay_ms(2000)
            .enable_metrics()
            .buffer_size(1000)
            .max_message_size(2097152) // 2MB
            .message_ttl_ms(7200000) // 2小时
            .custom_property("service".to_string(), "test-service".to_string())
            .build()
            .await
            .expect("Failed to build message bus");

        assert_eq!(bus.list_topics().await.unwrap().len(), 0);
    }

    #[tokio::test]
    async fn test_factory_methods() {
        // 测试默认工厂方法
        let bus1 = MessageBusUtils::create_default().await.unwrap();
        assert_eq!(bus1.list_topics().await.unwrap().len(), 0);

        // 测试内存工厂方法
        let bus2 = MessageBusUtils::create_memory().await.unwrap();
        assert_eq!(bus2.list_topics().await.unwrap().len(), 0);

        // 测试配置工厂方法
        let config = MessageBusConfig::default();
        let bus3 = MessageBusUtils::create_with_config(config).await.unwrap();
        assert_eq!(bus3.list_topics().await.unwrap().len(), 0);
    }

    #[tokio::test]
    async fn test_builder_validation() {
        // 测试无效配置
        let result = MessageBusBuilder::new()
            .max_connections(0) // 无效值
            .build()
            .await;
        
        assert!(result.is_err());
    }

    #[tokio::test]
    async fn test_unsupported_backends() {
        // 测试尚未实现的后端 - 测试无配置的情况
        let result = MessageBusBuilder::new()
            .bus_type(MessageBusType::Redis)
            .build()
            .await;
        
        assert!(result.is_err());
        let error_msg = result.err().unwrap().to_string();
        // Redis配置缺失时会先报配置错误
        assert!(error_msg.contains("Redis") && error_msg.contains("配置缺失"));
        
        // 测试有配置但功能未实现的情况
        let mut config = MessageBusConfig::default();
        config.bus_type = MessageBusType::Redis;
        config.redis = Some(crate::config::RedisConfig::default());
        
        let result = MessageBusBuilder::with_config(config)
            .build()
            .await;
        
        assert!(result.is_err());
        let error_msg = result.err().unwrap().to_string();
        println!("实际错误消息: {}", error_msg);
        // 有配置但功能未实现
        assert!(error_msg.contains("Redis") && (error_msg.contains("尚未实现") || error_msg.contains("未实现")));
    }
}